package com.tpfinal.agenda.view;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import com.asynccommand.framework.BaseCommand;
import com.asynccommand.framework.ICommandListener;
import com.tpfinal.agenda.controller.MainController;
import com.tpfinal.agenda.core.AgendaActionsIDs;
import com.tpfinal.agenda.view.renderers.ContactsTableModel;
import com.tpfinal.agenda.view.renderers.GoogleMapsViewer;

public class Main extends JFrame implements ICommandListener, ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 
	 */
	private JPanel contentPane;
	private JTable table;
	private ContactsTableModel tableModel;

	private JMenuItem mntmViewPersons;
	private JMenuItem mntmViewCompanies;
	private JMenuItem mntmViewAll;

	private MainController controller = MainController.get();
	private JMenuItem mntmAdd;
	private JMenuItem mntmDelete;
	private JMenuItem mntmModify;
	private JMenuItem mntmViewInMap;
	private JTextField searchField;
	private JMenuItem mntmSalir;

	/**
	 * Create the frame.
	 */
	public Main() {

		controller.register((ICommandListener) this);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		setTitle("Sistema de gesti�n de contactos - Listado de contactos");
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);

		JScrollPane scrollPane = new JScrollPane();

		contentPane.add(scrollPane, BorderLayout.CENTER);
		table = new JTable();
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		tableModel = new ContactsTableModel(table);

		table.setModel(tableModel);
		scrollPane.setViewportView(table);

		TableModel model = table.getModel();
		RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
		table.setRowSorter(sorter);

		searchField = new JTextField();
		contentPane.add(searchField, BorderLayout.AFTER_LAST_LINE);

		searchField.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				tableModel.render(searchField.getText());
			}
		});

		JMenuBar menuBar = new JMenuBar();
		contentPane.add(menuBar, BorderLayout.NORTH);

		JMenu mnSistema = new JMenu("Sistema");
		menuBar.add(mnSistema);
		
		mntmSalir = new JMenuItem("Salir");
		mntmSalir.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				dispose();
			}
		});
		mnSistema.add(mntmSalir);

		JMenu mnFiltros = new JMenu("Filtros");

		menuBar.add(mnFiltros);

		mntmViewPersons = new JMenuItem("Ver Personas");
		mntmViewPersons.addActionListener(this);

		mnFiltros.add(mntmViewPersons);

		mntmViewCompanies = new JMenuItem("Ver Empresas");
		mntmViewCompanies.addActionListener(this);
		mnFiltros.add(mntmViewCompanies);

		mntmViewAll = new JMenuItem("Ver Todos");
		mntmViewAll.addActionListener(this);
		mnFiltros.add(mntmViewAll);

		JMenu mnContact = new JMenu("Contacto");
		menuBar.add(mnContact);

		mntmAdd = new JMenuItem("Agregar");
		mntmAdd.addActionListener(this);
		mnContact.add(mntmAdd);

		mntmDelete = new JMenuItem("Eliminar");
		mntmDelete.addActionListener(this);
		mnContact.add(mntmDelete);

		mntmModify = new JMenuItem("Modificar");
		mntmModify.addActionListener(this);
		mnContact.add(mntmModify);

		mntmViewInMap = new JMenuItem("Ver en Mapa");
		mntmViewInMap.addActionListener(this);
		mnContact.add(mntmViewInMap);

		controller.loadContactsList();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == mntmViewAll) {
			tableModel.renderAll();
		} else if (e.getSource() == mntmViewCompanies) {
			tableModel.renderJustCompanies();
		} else if (e.getSource() == mntmViewPersons) {
			tableModel.renderJustPersons();
		} else if (e.getSource() == mntmAdd) {
			controller.setSelectedContact(null);
			ContactForm.getInstance().start();
		} else if (validateAction()) {
			if (e.getSource() == mntmDelete) {
				controller.deleteContact(tableModel.getSelectedContact());
			} else if (e.getSource() == mntmModify) {
				controller.setSelectedContact(tableModel.getSelectedContact());
				ContactForm.getInstance().start();
			} else if (e.getSource() == mntmViewInMap) {
				GoogleMapsViewer.view(tableModel.getSelectedContact()
						.getFullAddress());
			}
		}
	}

	protected boolean validateAction() {
		if (table.getSelectedRowCount() < 1) {
			JOptionPane.showMessageDialog(this, "Debe seleccionar un contacto",
					"Seleccione el contacto a modificar",
					JOptionPane.ERROR_MESSAGE);
			return false;
		}
		return true;
	}

	@Override
	public void onDone(int actionID, Map<String, Object> params) {

		switch (actionID) {

		case AgendaActionsIDs.GET_ALL_CONTACTS:

			controller.loadCitiesList();

			break;

		case AgendaActionsIDs.GET_ALL_CITIES:
		case AgendaActionsIDs.INSTERT_CONTACT:
		case AgendaActionsIDs.UPDATE_CONTACT:
		case AgendaActionsIDs.DELETE_CONTACT:

			EventQueue.invokeLater(new Runnable() {
				@Override
				public void run() {
					tableModel.addContacts(controller.getContactsList());
					tableModel.render();

				}
			});

		default:
			break;
		}

	}

	@Override
	public void onProgress(int actionID, Map<String, Object> params) {

	}

	@Override
	public void onError(int actionID, final Map<String, Object> params) {

		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				JOptionPane.showMessageDialog(Main.this,
						(String) params.get(BaseCommand.ERROR_MSG), "Error",
						JOptionPane.ERROR_MESSAGE);
			}
		});

	}

}
